package com.heima.search.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.heima.model.behavior.pojos.ApBehaviorEntry;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.search.feign.BehaviorFeign;
import com.heima.search.service.ApArticleSearchService;
import com.heima.search.service.ApUserSearchService;
import com.heima.utils.common.ApUserThreadLocal;
import org.apache.commons.lang3.StringUtils;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
public class ApArticleSearchServiceImpl implements ApArticleSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    /**
     * ES文章分页搜索
     *
     * @return
     */
    @Override
    public ResponseResult search(UserSearchDto dto) {

        //验证数据
        if (null == dto || StringUtils.isBlank(dto.getSearchWords())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }

        //从es中检索数据
        SearchRequest searchRequest = new SearchRequest("app_info_article");

        //创建布尔查询对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        //根据关键字模糊查询
        boolQueryBuilder.must(QueryBuilders.wildcardQuery("title", dto.getSearchWords()));

        //查询小于当前时间的数据
        boolQueryBuilder.filter(QueryBuilders.rangeQuery("publishTime").lte(dto.getMinBehotTime()));

        //创建条件构建器
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(boolQueryBuilder);

        //根据发布时间倒序排序
        searchSourceBuilder.sort("publishTime", SortOrder.DESC);

        //分页查询
        searchSourceBuilder.from(dto.getPageNum());
        searchSourceBuilder.size(dto.getPageSize());

        //添加构建器
        searchRequest.source(searchSourceBuilder);

        //查询数据
        SearchResponse searchResponse = null;
        try {
            searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            e.printStackTrace();
        }

        //从hits获取数据，封装返回
        SearchHit[] hits = searchResponse.getHits().getHits();
        List<Map> articleList = new ArrayList<>();

        //封装数据
        for (SearchHit hit : hits) {
            String sourceAsString = hit.getSourceAsString();
            Map map = JSONObject.parseObject(sourceAsString, Map.class);
            articleList.add(map);
        }

        //保存搜索历史
        insertSearch(dto.getEquipmentId(), dto.getSearchWords());


        return ResponseResult.okResult(articleList);
    }

    @Autowired
    private BehaviorFeign behaviorFeign;

    @Autowired
    private ApUserSearchService apUserSearchService;

    /**
     * 插入搜索记录
     *
     * @param equipmentId
     * @param searchWords
     */
    private void insertSearch(Integer equipmentId, String searchWords) {

        //获取用户id
        ApUser apUser = ApUserThreadLocal.getUser();
        if (null == apUser) {
            return;
        }

        //获取行为实体
        ApBehaviorEntry byUserIdOrEntry = behaviorFeign.findByUserIdOrEntryId(apUser.getId(), equipmentId);

        //调用方法保存搜索记录
        apUserSearchService.insert(byUserIdOrEntry.getId(), searchWords);
    }

}
